function varargout = checkModelStds(modelName, varargin)
% 函数功能：检查Simulink模型是否符合建模标准
% 输入参数：
%   modelName - 要检查的Simulink模型名称
%   varargin - 可选参数，用于指定环境和CI集成参数
% 输出参数：
%   varargout - 可变输出参数，包含检查结果结构体

% 检查Simulink Check许可证是否可用
if ~dig.isProductInstalled('Simulink Check')
    error('A Simulink Check license is not available.');
end

% 关闭所有已打开的模型
bdclose('all');

% 删除已存在的旧报告文件
% 基于规则第3条：使用getRptPath()从配置文件读取报告格式
rptFile = getRptPath('model standards report', modelName);
if exist(rptFile, 'file')
    delete(rptFile);
end

% 检查模型启动脚本是否存在
if ~exist(ProjectNamingManager.getNameStr('load command', modelName), 'file')
    error(['Model startup script ''', ProjectNamingManager.getNameStr('load command', modelName), ''' not found.']);
end

% 打开Simulink模型
disp(['Opening Simulink model ', modelName, '.']);
evalin('base', ProjectNamingManager.getNameStr('load command', modelName));

% 根据输入参数确定运行环境（CI或DEV）
if nargin > 2 && ~isempty(varargin{2})
    % CI环境：持续集成环境
    environment = 'CI';
    viewReport = false;  % CI环境下不自动打开报告
else
    % DEV环境：开发环境
    environment = 'DEV';
    viewReport = true;   % 开发环境下自动打开报告
end

% 使用集中配置函数获取报告格式
reportFormat = getReportFormatConfig('model standards', environment);

% 设置报告参数
reportName = ProjectNamingManager.getNameStr('model standards report', modelName);  % 报告名称
reportPath = ProjectPathManager.getDirPath('model standards', modelName);        % 报告路径

% 读取配置文件以获取检查ID（如果使用配置方法）
configFile = [ProjectNamingManager.getNameStr('model advisor configuration'), '.json'];

try

    checkResult = ModelAdvisor.run(modelName, ...
        'Configuration', configFile, ...      % 指定配置文件
        'Force', 'on', ...                    % 强制运行检查
        'ReportFormat', reportFormat, ...     % 报告格式
        'ReportPath', reportPath, ...         % 报告路径
        'ReportName', reportName);            % 报告名称

    
    % 使用MATLAB 2023b API生成摘要报告
    ModelAdvisor.summaryReport(checkResult);
    
    % 基于规则第2条：验证报告文件是否真正生成（不使用silent fallback）
    fullReportPath = fullfile(reportPath, [reportName, '.', reportFormat]);
    if ~exist(fullReportPath, 'file')
        % 报告文件不存在，明确报告错误（规则第2条）
        % 使用格式化字符串避免路径中的反斜杠被解释为转义字符
        error('checkModelStds:ReportNotGenerated', ...
            'Model Advisor report was not generated. Expected file: %s. Please check if ModelAdvisor.run() executed correctly and the report path is accessible.', ...
            fullReportPath);
    end
    
    % 报告文件确实存在，设置成功消息
    result.Message = ['Model Advisor report for ', modelName, ' is successfully generated.'];
    
    % 如果在开发模式下，自动打开报告
    if viewReport
        try
            % 根据操作系统选择不同的打开方式
            if ispc
                winopen(fullReportPath);  % Windows系统
            elseif ismac
                system(['open "' fullReportPath '"']);  % macOS系统
            else
                system(['xdg-open "' fullReportPath '"']);  % Linux系统
            end
        catch openErr
            % 基于规则第2条：明确报告打开失败（但不影响整体成功）
            warning('checkModelStds:CannotOpenReport', ...
                'Report generated successfully but could not be opened automatically: %s', openErr.message);
        end
    end
    
catch ME
    % 如果发生错误，关闭模型
    close_system(modelName, 0);
    rethrow(ME);  % 重新抛出异常
end

% 为CI集成处理结果
if nargin > 2 && ~isempty(varargin{2}) && ~strcmpi(varargin{2}, 'DEV')
    % 初始化结果结构体
    result.Method = 'checkModelStds';     % 方法名称
    result.Component = modelName;         % 组件名称
    result.NumTotal = 0;                  % 总检查数
    result.NumPass = 0;                   % 通过数
    result.NumWarn = 0;                   % 警告数
    result.NumFail = 0;                   % 失败数
    result.Results = [];                  % 详细结果
    
    % 从checkResult结构中提取结果
    if ~isempty(checkResult)
        for i = 1:length(checkResult)
            % 查找对应模型的检查结果
            if strcmpi(checkResult{i}.system, modelName)
                result.NumTotal = checkResult{i}.geninfo.allCt;    % 总检查数
                result.NumPass = checkResult{i}.geninfo.passCt;    % 通过数
                result.NumWarn = checkResult{i}.geninfo.warnCt;    % 警告数
                result.NumFail = checkResult{i}.geninfo.failCt;    % 失败数
                % 根据检查结果确定输出状态
                if result.NumFail > 0
                    result.Outcome = -1;  % 有失败项
                elseif result.NumWarn > 0
                    result.Outcome = 0;   % 有警告项
                else
                    result.Outcome = 1;   % 全部通过
                end
                result.Results = checkResult{i};  % 保存详细结果
                break;
            end
        end
    end
    varargout{1} = result;  % 设置输出参数
else
    % 非CI环境下的输出处理
    if nargout > 0
        varargout{1} = result;
    end
end

% 删除临时文件夹
if exist('rtwgen_tlc', 'dir')
    rmdir('rtwgen_tlc', 's');  % 删除rtwgen_tlc文件夹及其内容
end
if exist('sldv_output', 'dir')
    rmdir('sldv_output', 's')  % 删除sldv_output文件夹及其内容
end

% 关闭Simulink模型
disp(['Closing Simulink model ', modelName, '.']);
close_system(modelName, 0);

% 显示结果消息
disp(result.Message);

end
